package cn.jll.dev.utils.common;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: 日期工具
 * @author: jinleilei
 * @Version: v1.0
 **/
public class DateUtils {

    /**
     * pattern: yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_TIME_DEFAULT = "yyyy-MM-dd HH:mm:ss";

    /**
     * pattern: yyyy/MM/dd HH:mm:ss
     */
    public static final String FORMAT_TIME_TILT = "yyyy/MM/dd HH:mm:ss";

    /**
     * pattern: yyyyMMddHHmmss
     */
    public static final String FORMAT_TIME_ROW = "yyyyMMddHHmmss";

    /**
     * pattern: yyyy-MM-dd-HH-mm
     */
    public static final String FORMAT_TIME_LINE = "yyyy-MM-dd-HH-mm";

    /**
     * pattern:yyyy-MM-dd
     */
    public static final String FORMAR_DATE_DEFAULT = "yyyy-MM-dd";

    /**
     * pattern: yyyy/MM/dd
     */
    public static final String FORMAT_DATE_TILT = "yyyy/MM/dd";

    /**
     * pattern:yyyy-MM
     */
    public static final String FORMAT_DATE_LINE = "yyyy-MM";

    /**
     * pattern:yyyyMMddHHmmssSSS
     */
    public static final String FORMAT_TIMESTEMP_ROW = "yyyyMMddHHmmssSSS";

    private static Map<String, DateFormat> context = new ConcurrentHashMap<String, DateFormat>();

    /**
     * 创建DateFormat对象。
     *
     * @param pattern 时间模式
     * @param locale  区域语言
     * @return DateFormat
     */
    public static DateFormat getDateFormat(String pattern, Locale locale) {
        DateFormat format = null;
        if (context.containsKey(pattern)) {
            format = context.get(pattern);
        } else {
            format = new SimpleDateFormat(pattern, locale);
            context.put(pattern, format);
        }
        return format;
    }

    /**
     * 多少天后的时间
     *
     * @param day 多少天后
     * @param d   原始时间
     * @return date 变后时间
     */
    public static Date afterTime(int day, Date d) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.setTimeInMillis(Calendar.getInstance().getTimeInMillis() + day * 3600 * 24 * 1000);
        Date date = calendar.getTime();
        return date;
    }

    /**
     * 多少天之前的时间
     *
     * @param day      多少天之前
     * @param calendar 原始时间
     * @return date 变后时间
     */
    public static Date beforeTime(int day, Calendar calendar) {
        calendar = Calendar.getInstance();
        calendar.setTimeInMillis(Calendar.getInstance().getTimeInMillis() - day * 3600 * 24 * 1000);
        Date date = calendar.getTime();
        return date;
    }

    /**
     * 获取明天的日期
     *
     * @param date 原始时间
     * @return date 变后时间
     */
    public static Date getNextDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +1);
        date = calendar.getTime();
        return date;
    }

    /**
     * 格式化时间字符串为指定格式字符串。
     *
     * @param srcPattern 原时间模式
     * @param desPattern 目标时间模式
     * @param srcDate    原时间
     * @return 格式化时间字符串
     * @throws ParseException 解析异常
     */
    public static String format(String srcPattern, String desPattern, String srcDate) {
        String ret = "";
        try {
            DateFormat format = getDateFormat(srcPattern, Locale.getDefault());
            Date date = format.parse(srcDate);
            ret = getDateFormat(desPattern, Locale.getDefault()).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 格式化时间。
     *
     * @param desPattern 指定时间模式
     * @param date       时间
     * @return 格式化时间
     */
    public static String format(String desPattern, Date date) {
        DateFormat format = getDateFormat(desPattern, Locale.getDefault());
        return format.format(date);
    }

    /**
     * 返回当前年份。
     *
     * @return year
     */
    public static int getThisYear() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }


    /**
     * 格式化日期返回
     *
     * @param date
     * @param format
     * @return
     */
    public static String formatDate(Date date, String format) {
        String res = "";
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            if (null != date) {
                res = sdf.format(date);
            }
        } catch (Exception e) {
        }
        return res;
    }

    /**
     * String转Date
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date d = null;
        try {
            d = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            d = new Date();
        }
        return d;
    }


    /**
     * 获取时间差
     *
     * @param begin
     * @param end
     * @return
     */
    public static long diffTime(Date begin, Date end) {
        return (end.getTime() - begin.getTime());
    }


    /**
     * 获取下一个月
     *
     * @param date 日期Date
     * @return Date
     */
    public static Date nextMonth(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.MONTH, +1);
        gc.set(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH), gc.get(Calendar.DATE));
        return gc.getTime();
    }

    /**
     * 获取当前月第一天
     *
     * @return
     */
    public static Date firstDayofMonth() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, 1);
        return ca.getTime();
    }

    /**
     * 获取当前月最后一天
     *
     * @return
     */
    public static Date lastDayofMonth() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return ca.getTime();
    }

    /**
     * 当前时间减一个月
     *
     * @param date
     * @return
     */
    public static Date minusMonth(Date date, int n) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -n);
        return calendar.getTime();
    }

    /**
     * 获取时间差
     *
     * @param start
     * @param end
     * @return
     */
    public static String timeDiff(Date start, Date end) {
        long l = end.getTime() - start.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long ms = (l - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return day + "天" + hour + "小时" + min + "分" + s + "秒" + ms + "毫秒";
    }

    /**
     * 将时间戳转换为时间
     *
     * @param date    时间stamp
     * @param pattern 格式，默认 yyyy-MM-dd
     * @return
     */
    public static String stampToDate(long date,  String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(new Date(date));
    }

    /**
     * 获取前一天
     *
     * @param date
     * @return
     */
    public static Date getPreDayDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /**
     * 获取前一天
     *
     * @param date
     * @return yyyy-MM-dd
     */
    public static String getPreDayStr(Date date) {
        return formatDate(getPreDayDate(date), FORMAT_DATE_LINE);
    }
}
